#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=1e5+10;
LL n,m,head[MAXN],pre[MAXN],cnt,yl,yr,sumv[MAXN*4],addv[MAXN*4],v;
struct point
{
	LL sub,num,fa,top,depth,son,sum,maxr;
}p[MAXN];
struct edge
{
	LL v,next;
}e[MAXN*2];
void addedge(LL x,LL y)
{
	e[cnt]=(edge){y,head[x]};
	head[x]=cnt++;
	return;
}
void push_up(LL o)
{
	LL lc=o<<1,rc=o<<1|1;
	sumv[o]=sumv[lc]+sumv[rc];
	return;
}
void push_down(LL o,LL l,LL r)
{
	if(!addv[o])return;
	LL lc=o<<1,rc=o<<1|1,mid=(l+r)>>1;
	addv[lc]+=addv[o];
	addv[rc]+=addv[o];
	sumv[lc]+=addv[o]*(mid-l+1);
	sumv[rc]+=addv[o]*(r-mid);
	addv[o]=0;
	return;
}
void dfs1(LL u,LL depth,LL last)
{
	LL t=0;
	p[u].sum=1;
	p[u].fa=last;
	p[u].depth=depth;
	for(LL i=head[u];~i;i=e[i].next)
	{
		LL v=e[i].v;
		if(v==last)continue;
		dfs1(v,depth+1,u);
		p[u].sum+=p[v].sum;
		if(p[v].sum>t)
		{
			t=p[v].sum;
			p[u].son=v;
		}
	}
	return;
}
void dfs2(LL u,LL top)
{
	p[u].top=top;
	pre[++cnt]=u;
	p[u].sub=cnt;
	if(p[u].son)dfs2(p[u].son,top);
	for(LL i=head[u];~i;i=e[i].next)
	{
		LL v=e[i].v;
		if(v==p[u].fa||v==p[u].son)continue;
		dfs2(v,v);
	}
	p[u].maxr=cnt;
	return;
}
void build(LL o,LL l,LL r)
{
	if(l==r)
	{
		sumv[o]=p[pre[l]].num;
		return;
	}
	LL lc=o<<1,rc=o<<1|1,mid=(l+r)>>1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	push_up(o);
	return;
}
void update(LL o,LL l,LL r)
{
	if(yl<=l&&r<=yr)
	{
		addv[o]+=v;
		sumv[o]+=(r-l+1)*v;
		return;
	}
	LL lc=o<<1,rc=o<<1|1,mid=(l+r)>>1;
	push_down(o,l,r);
	if(yl<=mid)update(lc,l,mid);
	if(yr>mid)update(rc,mid+1,r);
	push_up(o);
	return;
}
LL query_sum(LL o,LL l,LL r)
{
	if(yl<=l&&r<=yr)return sumv[o];
	push_down(o,l,r);
	LL ret=0,lc=o<<1,rc=o<<1|1,mid=(l+r)>>1;
	if(yl<=mid)ret=query_sum(lc,l,mid);
	if(yr>mid)ret+=query_sum(rc,mid+1,r);
	return ret;
}
LL query(LL o)
{
	LL ret=0;
	while(true)
	{
		LL f=p[o].top;
		yl=p[f].sub;yr=p[o].sub;
		ret+=query_sum(1,1,n);
		if(f==1)break;
		o=p[f].fa;
	}
	return ret;
}
int main()
{
	scanf("%lld%lld",&n,&m);
	memset(head,-1,sizeof(head));
	for(LL i=1;i<=n;++i)scanf("%lld",&p[i].num);
	for(LL i=1;i<n;++i)
	{
		LL x,y;
		scanf("%lld%lld",&x,&y);
		addedge(x,y);
		addedge(y,x);
	}
	cnt=0;
	dfs1(1,1,0);
	dfs2(1,1);
	build(1,1,n);
	while(m--)
	{
		LL t1,x;
		scanf("%lld%lld",&t1,&x);
		if(t1==1)
		{
			LL t2;
			scanf("%lld",&t2);
			yl=yr=p[x].sub;
			v=t2;
			update(1,1,n);
		}
		else if(t1==2)
		{
			LL t2;
			scanf("%lld",&t2);
			yl=p[x].sub;
			yr=p[x].maxr;
			v=t2;
			update(1,1,n);
		}
		else printf("%lld\n",query(x));
	}
	return 0;
}
